#!/usr/bin/env python

"""Track me

This script will
    1. try to guess your current location (by using your public ip address)
    2. capture your photo if a webcam is attached
    3. send the above info to your blog by email.

Pre-requisites :
    1. a working internet connection
    2. opencv python module is already installed
    3. the following vars are defined in your shell env
        TEMP
        SMTP_SERVER
        SMTP_USER
        SMTP_PASS
        TO_ADDR
    4. the following modules are present in the same directory as this module.
        mutils.py
        send_email.py
        webcam.py
        pygeoip.py
    5. maxmind geolite city database is already downloaded.
       http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
"""

__version__ = "$Revision$"
# Last Modified on $Date$
# by $Author$
# from $Source$

import os
import sys
import time
from datetime import date, datetime
import urllib2

import mutils
from mutils import log
import webcam
import send_email
import pygeoip



# Number of days before sending another update
refresh_interval = 7

# Number of seconds before checking for internet connection
sleep_duration = 600

tmp = os.getenv('TEMP')
photo_name = 'my-pic'
photo_extn = 'jpeg'
geolite_city_db = os.path.join(os.getenv('HOME'), '.GeoLiteCity.dat')

attach_list = []


def get_loc_details():
    """ Parse current location details from Maxmind website
    """
    log.debug('Finding current location details')

    my_ip = urllib2.urlopen('http://www.whatismyip.org/').read()

    gic = pygeoip.GeoIP(geolite_city_db)
    loc = gic.record_by_addr(my_ip)
    my_city = loc['city']

    log.debug('My current ip = %s', my_ip)
    log.debug('My current location = %s', my_city)
    log.debug('Dump of Location Details : %s' % str(loc))

    subject = 'Near %s ((nogallery))' % my_city
    body = '''Currently I am somewhere near %s. (Automatically guessed from my ip address %s)

              Additional Details:
                  Country   = %s
                  Region    = %s
                  Latitude  = %s
                  Longitude = %s
           ''' % (my_city, my_ip,
                  loc['country_name'],
                  loc['region_name'],
                  loc['latitude'],
                  loc['longitude'],
                  )


    return (subject, body)


def capture_photos():
    """ Capture 4 photos from webcam
    """
    log.debug('Taking Photos')

    cdate = date.today().isoformat()

    for i in range(0, 4):
        #File name will be something like my_pic_1_2009-09-09.jpeg
        file_name = '%s-%s-%s.%s' %(photo_name, cdate, str(i), photo_extn)
        file_name = os.path.join(tmp, file_name)

        webcam.capture_image(file_name)

        #Somehow, the first photo comes garbled. So skipping it
        if i:
            attach_list.append(file_name)
            log.debug('Captured %s' % file_name)

        time.sleep(1)


def open_gate():
    """Checks whether script can continue. If not allowed, exits.
    """
    now = datetime.now()
    then = mutils.unpickle()

    # If mutils.unpickle() returns None, don't do anything.
    # Otherwise, check whether refresh_interval has elapsed.
    # If not exit
    if then:
        diff = now - then

        if diff.days < refresh_interval:
            sys.exit(0)

def close_gate():
    """Save current execution time for next run.
    """
    now = datetime.now()
    mutils.pickle(now)

def main():
    open_gate()

    while True:

        if mutils.online():
            log.debug('Started')


            (subject, body) = get_loc_details()
            capture_photos()
            send_email.send_email(os.getenv('SMTP_SERVER'),
                                  os.getenv('SMTP_USER'),
                                  os.getenv('SMTP_PASS'),
                                  os.getenv('SMTP_USER'),
                                  [os.getenv('TO_ADDR')],
                                  subject,
                                  body,
                                  attach_list,
                                 )
            close_gate()

            log.debug('Finished')
            break

        else:
            time.sleep(sleep_duration)


#The following code will be executed only if called as stand-alone script.
#Skipped if imported as module
if __name__ == '__main__':
    sys.exit(main())

